import { ElDialog } from "element-plus";
import { isFunction } from "lodash-es";
import { computed, defineComponent, h, ref } from "vue";

type UseModelOptions = {
  title?: string | ((source: any) => string);
  width?: string | number;
  destroyOnClose?: boolean;

  onClose?: () => void;
  onOpen?: () => void;
};

export default (options: UseModelOptions = {}) => {
  const visible = ref(false);
  const source = ref();

  const events = {
    onOpen() {
      options?.onOpen?.();
    },
    onClose() {
      options?.onClose?.();
    },
  };

  const modalApi = {
    close() {
      visible.value = false;
    },
  };

  const Modal = defineComponent(
    (props, { slots }) => {
      const slotDefault = slots.default?.();

      const { title, destroyOnClose = true, ...rest } = options;

      const showTitle = computed(() => {
        return isFunction(title) ? title(source.value) : title;
      });

      return () =>
        h(
          ElDialog,
          {
            modelValue: visible.value,
            "onUpdate:modelValue": (val: boolean) => (visible.value = val),
            title: showTitle.value,
            destroyOnClose,
            ...rest,
            ...props,
            ...events,
          } as any,
          slotDefault
            ? h(slotDefault[0], { modalApi, source: source.value }, undefined)
            : undefined
        );
    },
    { props: {} }
  );

  const api = {
    open(payload?: any) {
      source.value = payload;
      visible.value = true;
    },
    ...modalApi,
  };

  return [Modal, api, source] as [typeof Modal, typeof api, typeof source];
};
